package nmp.remote;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import nmp.gui.CGroupListAdapter;
import nmp.gui.CWifiConfigDlg;
import nmp.lib.CNmpDevice;
import nmp.lib.CNmpDongle;
import nmp.lib.CNmpWifiManage;
import nmp.lib.CNmpCmd.*;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;

import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class NmpGatewaySelect extends Activity 
{
	public enum E_WIFI_INFO_TYPE {
		E_WIFI_INFO_TYPE_NORMAL,
		E_WIFI_INFO_TYPE_CUSTOMIZED,
		E_WIFI_INFO_TYPE_SCAN
	};
	
	private enum CONTROL_STATE {
		NONE,
		READY,
		START,
		GET_WIFI_LIST,
		CONNECT_PREPARE,
		CONNECTING,
		CHECK_CONNECT_READY,
		DISCONNECTING,
		CHECK_DISCONNECT_READY,
		CLOSE
	};
	
	private class WifiSelectItem extends NmpWifiInfo {
		E_WIFI_INFO_TYPE type;
	};
		
	private CNmpDongle mNmpDevice = null;
	private ListView mListView;
	private ArrayList<WifiSelectItem> mGatewaySelectList;
	private WifiSelectItem mSelectedGatewayItem;
	private Context mContext;
	private ProgressDialog mGatewawyListBusyDialog = null;
	private ProgressDialog mConnectBusyDialog = null;
	private Handler mHandlerTime;
    private Runnable mTimerRun;
	private CONTROL_STATE mState;
	private CNmpWifiManage mWifiManage;
	
	private String mStrCancel;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		Log.d(this.toString(),"onCreate start");
		super.onCreate(savedInstanceState);
		setContentView(R.layout.gateway_select);	
		
		mContext = this;
		mListView = (ListView)findViewById(R.id.listViewAdress);
		mWifiManage = new CNmpWifiManage(this);
		
		mStrCancel = this.getResources().getString(R.string.cancel);
		
		mGatewawyListBusyDialog = new ProgressDialog(this);  
		mGatewawyListBusyDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		mGatewawyListBusyDialog.setTitle(this.getString(R.string.get_gateway_device_list));
		mGatewawyListBusyDialog.setIndeterminate(false);
		mGatewawyListBusyDialog.setCancelable(true);
		mGatewawyListBusyDialog.setButton(ProgressDialog.BUTTON_NEUTRAL,mStrCancel,new DialogInterface.OnClickListener(){  
			  
            public void onClick(DialogInterface dialog, int which) {
            	UpdateWifiList(null);
                dialog.cancel();  
                SetToState(CONTROL_STATE.READY);
            } 
        });
		
		mConnectBusyDialog = new ProgressDialog(this);  
		mConnectBusyDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		mConnectBusyDialog.setTitle(this.getString(R.string.connect_to_dongle_device));  
		mConnectBusyDialog.setIndeterminate(false);
		mConnectBusyDialog.setCancelable(true);
		mConnectBusyDialog.setButton(ProgressDialog.BUTTON_NEUTRAL,mStrCancel,new DialogInterface.OnClickListener(){  
			  
            public void onClick(DialogInterface dialog, int which) {   
            	ConnectToWifiDone();
                dialog.cancel();
            } 
        });		
		
		
	    Log.d(this.toString(),"onCreate end");
	}
	
	@Override
	protected void onDestroy() {
		Log.d(this.toString(),"onDestroy start");
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.d(this.toString(),"onDestroy stop");
	}
	@Override
	protected void onPause() {
		Log.d(this.toString(),"onPause start");
		// TODO Auto-generated method stub
		SetToState(CONTROL_STATE.CLOSE);		
		NmpDeviceClose();		
		mWifiManage.PrefPasswordSave();			
		super.onPause();
		Log.d(this.toString(),"onPause stop");
	}
	@Override
	protected void onPostCreate(Bundle savedInstanceState) {
		Log.d(this.toString(),"onPostCreate start");
		// TODO Auto-generated method stub
		super.onPostCreate(savedInstanceState);
		Log.d(this.toString(),"onPostCreate stop");
	}
	@Override
	protected void onPostResume() {
		Log.d(this.toString(),"onPostResume start");
		// TODO Auto-generated method stub
		super.onPostResume();
		Log.d(this.toString(),"onPostResume stop");
	}
	@Override
	protected void onRestart() {
		Log.d(this.toString(),"onRestart start");
		// TODO Auto-generated method stub
		super.onRestart();
		Log.d(this.toString(),"onRestart stop");
	}
	@Override
	protected void onResume() {
		Log.d(this.toString(),"onResume start");
		// TODO Auto-generated method stub
		super.onResume();
		SetToState(CONTROL_STATE.NONE);		
		NmpDeviceOpen();				
		Log.d(this.toString(),"onResume stop");
	}
	@Override
	protected void onStart() {
		Log.d(this.toString(),"onStart start");
		// TODO Auto-generated method stub		
		super.onStart();
		
		/*//for unit test 
		ArrayList<NmpWifiInfo> wifilist = new ArrayList<NmpWifiInfo>();
		NmpWifiInfo item = new NmpWifiInfo();
		item.ssid = "WalaceChuang";
		item.password = "123468";
		item.protect = "WPA";
		item.status = 0;
		item.strength= 90;
		wifilist.add(item);
		
		item = new NmpWifiInfo();
		item.ssid = "Jericho";
		item.password = "asdfas468";
		item.protect = "WPA";
		item.status = 1;
		item.strength= 50;
		wifilist.add(item);	

		item = new NmpWifiInfo();
		item.ssid = "nICK CHUE";
		item.password = "ASDFWQWE";
		item.protect = "WPA";
		item.status = 0;
		item.strength= 0;
		wifilist.add(item);				
		
		UpdateWifiList(wifilist);
		*/
		Log.d(this.toString(),"onStart stop");
	}
	@Override
	protected void onStop() {
		Log.d(this.toString(),"onStop start");

		super.onStop();
		Log.d(this.toString(),"onStop stop");
	}
		

	private void ConnectResultHandle(boolean connect) {
    	    		
		if(IsState(CONTROL_STATE.NONE)) {
			if(connect) {
				RescanWifiList();
			} else {
				UpdateWifiList(null);
			}
		} else if(IsState(CONTROL_STATE.CONNECTING) || 
				IsState(CONTROL_STATE.CHECK_CONNECT_READY)) {
			if(connect) {
				RescanWifiList();
			} else {
				mNmpDevice.ReConnect(3000);
			}
		} else {
			if(connect) {				
			} else {
				SetToState(CONTROL_STATE.NONE);
			}			
		}
	}
	 
	private void NmpDeviceOpen() {
	    	
		NmpDeviceClose();
    	
		mNmpDevice = new CNmpDongle(this)
		{			
			public void DeviceStatus(int status){
				
				switch(status) {
					case CNmpDevice.DEVICE_STATUS_DISCONNECT:
						ConnectResultHandle(false);
						break;
					case CNmpDevice.DEVICE_STATUS_CONNECT:
						ConnectResultHandle(true);
						break;
				}
				
			}
			
			public void GetIdentifyResponse(NmpCmdIdentifyInfo info) {
				
			}
			
			public void GetWifiListResponse(NmpCmdWifiList info) {
				if(IsState(CONTROL_STATE.GET_WIFI_LIST)) {
					UpdateWifiList(info.list);
					mGatewawyListBusyDialog.dismiss();	
					mState = CONTROL_STATE.READY;
				}
			}

			public void GetWifiConnectResponse(NmpCmdBase info) {
				if(IsState(CONTROL_STATE.CONNECTING)) {
					SetToState(CONTROL_STATE.CHECK_CONNECT_READY);
					CheckIsConnectCmdDelay(0);						
				}				
			}
			
			public void GetWifiDisConnectResponse(NmpCmdBase info) {
				if(IsState(CONTROL_STATE.DISCONNECTING)) {
					SetToState(CONTROL_STATE.CHECK_DISCONNECT_READY);
					CheckIsConnectCmdDelay(0);					
				}
			}
			
			public void GetDeviceInfoResponse(NmpCmdDeviceInfo info) {
				
			}	

			public void GetWifiConfigResponse(NmpCmdBase info) {
				
			}	
			
			public void GetWifiIsConnectedResponse(NmpCmdIsConnected info) {
				
				if(IsState(CONTROL_STATE.CHECK_CONNECT_READY)) {
					if(info.isconnected == 1) {						
						ConnectToWifiDone();								
						RescanWifiList();
					} else {
						CheckIsConnectCmdDelay(1000);
					}
				}	
				
				if(IsState(CONTROL_STATE.CHECK_DISCONNECT_READY)) {
					if(info.isconnected == 1) {						
						CheckIsConnectCmdDelay(1000);
					} else {
						SetToState(CONTROL_STATE.READY);
					}						
				}
			}	
			
		};   
		
		if(!mNmpDevice.Connect()) {
			ConnectResultHandle(false);				
		}		
    }
    
    private void NmpDeviceClose() {
    	if(mNmpDevice != null) {
    		mNmpDevice.Disconnect();
    		mNmpDevice = null;    		
    	}    	    	
    }   

	private void RescanWifiList() {
		SetToState(CONTROL_STATE.GET_WIFI_LIST);
		mGatewawyListBusyDialog.show(); 
		mNmpDevice.SendGetWifiListCmd();		
	}
	

	private void SelectWifiItemHandle(int selected_index)  {
		mSelectedGatewayItem = mGatewaySelectList.get(selected_index);
	
		if(mSelectedGatewayItem.type == E_WIFI_INFO_TYPE.E_WIFI_INFO_TYPE_CUSTOMIZED) {
			
			SetToState( CONTROL_STATE.CONNECT_PREPARE);
			CWifiConfigDlg dlg = new CWifiConfigDlg(mContext) {
	    		public void Result(NmpWifiInfo wifiinfo) {
	    			if(wifiinfo == null) {
	    				SetToState(CONTROL_STATE.READY);
	    			} else {
	    				SetToState(CONTROL_STATE.CONNECTING);
	    				ConnectToWifi(wifiinfo);
	    			}
	    		}				
			};
			dlg.show();
			
		} else if (mSelectedGatewayItem.type == E_WIFI_INFO_TYPE.E_WIFI_INFO_TYPE_SCAN){
			RescanWifiList();			
		} else if (mSelectedGatewayItem.type == E_WIFI_INFO_TYPE.E_WIFI_INFO_TYPE_NORMAL) {
					
			if(mSelectedGatewayItem.status == 0) {	
				SetToState( CONTROL_STATE.CONNECT_PREPARE);
				CWifiConfigDlg dlg = new CWifiConfigDlg(mContext,(NmpWifiInfo)mSelectedGatewayItem) {
		    		public void Result(NmpWifiInfo wifiinfo) {
		    			if(wifiinfo == null) {
		    				SetToState(CONTROL_STATE.READY);
		    			} else {			    				
		    				SetToState( CONTROL_STATE.CONNECTING);
		    				ConnectToWifi(wifiinfo);
		    			}
		    		}				
				};
				dlg.SetSSIDEnable(false);
				dlg.SetProtectEnable(false);
				dlg.show();		
				
			} else {
				
				AlertDialog.Builder alert = new AlertDialog.Builder(this);
				alert.setTitle("Disconnect");
				alert.setMessage("Are you sure to disconnect");
				
				alert.setPositiveButton("Disconnect", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) {
		            	SetToState( CONTROL_STATE.DISCONNECTING);
		            	mNmpDevice.SendWifiDisconnectCmd();
		            	dialog.cancel();		            	
		              }
		            });
		 
	            alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
	              public void onClick(DialogInterface dialog, int whichButton) {
	            	  dialog.cancel();
	            	  SetToState(CONTROL_STATE.READY);
	              }
	            });			
				
			}	
		}
	}	

	private ArrayList<WifiSelectItem> ConvertToWifiSelectList(ArrayList<NmpWifiInfo> wifilist) {
		NmpWifiInfo wifiinfo;
		WifiSelectItem item;
		ArrayList<WifiSelectItem> list;
		
		list = new ArrayList<WifiSelectItem>();
				
		if(wifilist != null) {
			Iterator<NmpWifiInfo> iterator = wifilist.iterator();			
	        while(iterator.hasNext()) {
	        	wifiinfo = (NmpWifiInfo) iterator.next();	        	
	        	item = new WifiSelectItem();
	        	
	        	item.ssid = wifiinfo.ssid;
	        	item.protect = wifiinfo.protect;
	        	item.strength = wifiinfo.strength;
	        	item.status  = wifiinfo.status;
	        	item.password = wifiinfo.password;
	        	item.type = E_WIFI_INFO_TYPE.E_WIFI_INFO_TYPE_NORMAL;
	        	list.add(item);        	
	        }			
		}
		
		item = new WifiSelectItem();
		item.ssid = "Manual SSID";
		item.protect = "";
		item.status  = 0;
		item.password = "";
		item.type = E_WIFI_INFO_TYPE.E_WIFI_INFO_TYPE_CUSTOMIZED;
		list.add(item); 
		
		item = new WifiSelectItem();
		item.ssid = "Scan WIFI access point";
		item.protect = "";
		item.status  = 0;
		item.password = "";
		item.type = E_WIFI_INFO_TYPE.E_WIFI_INFO_TYPE_SCAN;
		list.add(item); 	
		
		return list;
	}
	
	private void ConnectToWifi(NmpWifiInfo wifiinfo) {
		mWifiManage.PrefPasswordSet(wifiinfo.ssid, wifiinfo.password);
		mNmpDevice.SendWifiConnectCmd(wifiinfo.ssid,wifiinfo.protect, wifiinfo.password);			
		mConnectBusyDialog.show();
	}
	
	
	private void CheckIsConnectCmdDelay(int duration) {
		
		if(duration == 0) {
			mNmpDevice.SendWifiIsConnectedCmd();
		} else {			
			mHandlerTime = new Handler();		
			mTimerRun = new Runnable(){
			    public void run() {		
			    	if(mState == CONTROL_STATE.CHECK_CONNECT_READY 
			    			|| mState == CONTROL_STATE.CHECK_DISCONNECT_READY  )
			    		mNmpDevice.SendWifiIsConnectedCmd();	    	
			    }
			};			  
			mHandlerTime.postDelayed(mTimerRun, duration);
			
		}
	}

	private void ConnectToWifiDone() {		
		if(mState != CONTROL_STATE.CHECK_CONNECT_READY)
			return;		
		mConnectBusyDialog.dismiss();		
		SetToState(CONTROL_STATE.READY);
	}
  
	private void UpdateWifiList(ArrayList<NmpWifiInfo> wifilist) {
	
		mWifiManage.UpdateWifiListPassword(wifilist);
		mGatewaySelectList = ConvertToWifiSelectList(wifilist);
		
		if(mGatewaySelectList == null)
			return;
		
		SimpleAdapter listItemAdapter;
		List<Map<String, Object>> listItem;    	
		int max_strength = 100;
		String adapter_identify_list[] = new String[] {"ItemTitle", "ItemText","ItemImage","ItemCheck"};
		int adapter_resource_list[] = new int[] {R.id.listtextViewTitle,R.id.listtextViewContent,R.id.listimage,R.id.listImageCheck} ;
		int[] StrengthImage = { R.drawable.signal_strength_l, R.drawable.signal_strength_m, R.drawable.signal_strength_h};
		
		listItem = new ArrayList<Map<String, Object>>();    
		
		Iterator<WifiSelectItem> iterator = mGatewaySelectList.iterator();
		WifiSelectItem item;
		Map<String, Object> map;
		
		
		
        while(iterator.hasNext()) {
        	
        	item = (WifiSelectItem) iterator.next();	
        	if(item.type == E_WIFI_INFO_TYPE.E_WIFI_INFO_TYPE_NORMAL) {		        	
		        map = new HashMap<String, Object>();  
		        map.put(adapter_identify_list[0], item.ssid);  
		        map.put(adapter_identify_list[1], 
		        		getString(R.string.protect) + " : " + item.protect + "  " +
		        		getString(R.string.strength)  + " : " + item.strength);
		        		//item.strength + " status:" + item.status);
		        int strength_level;
		        if(item.strength > (2*max_strength/3))
		        	strength_level = 2;
		        else if (item.strength > (max_strength/3))
		        	strength_level = 1;
		        else 
		        	strength_level = 0;		       
		        map.put(adapter_identify_list[2], StrengthImage[strength_level]);
		        if(item.status == 1) {
		        	map.put(adapter_identify_list[3], R.drawable.checkon);
		        } else {
		        	map.put(adapter_identify_list[3], R.drawable.checkoff);
		        }
		        listItem.add(map);
		        
        	} else if (item.type == E_WIFI_INFO_TYPE.E_WIFI_INFO_TYPE_CUSTOMIZED) {
		        map = new HashMap<String, Object>();  
		        map.put(adapter_identify_list[0], getString(R.string.manual_configuration));  
		        map.put(adapter_identify_list[1], getString(R.string.manual_configuration_for_hide_ssd));
		        map.put(adapter_identify_list[2], R.drawable.hand);
		        map.put(adapter_identify_list[3], R.drawable.checkoff);
		        listItem.add(map);  
        	} else if  (item.type == E_WIFI_INFO_TYPE.E_WIFI_INFO_TYPE_SCAN) {
		        map = new HashMap<String, Object>();  
		        map.put(adapter_identify_list[0], getString(R.string.refresh));  
		        map.put(adapter_identify_list[1], getString(R.string.refresh_gateway_device_list));  
		        map.put(adapter_identify_list[2], R.drawable.refresh);	 
		        map.put(adapter_identify_list[3], R.drawable.checkoff);
		        listItem.add(map);  		        
        	} else {
        	}
	              	
        }       

        listItemAdapter = new SimpleAdapter(this,listItem,
        		R.layout.wifilistitem,adapter_identify_list,adapter_resource_list);  
        
        mListView.setAdapter(listItemAdapter);
       
	    mListView.setOnItemClickListener(new OnItemClickListener() {  
	    	public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {  
	    		SelectWifiItemHandle(arg2);
            }  
        });		
	}	
	
	private void SetToState(CONTROL_STATE state) {
		Log.e(this.toString(),"Current State:" + state);		
		mState = state;
	}    
	
	private boolean IsState(CONTROL_STATE state) {
		Log.e(this.toString(),"Current State:" + mState + " < === > Check State:" + state );			
		return (mState == state);
	}    	
	

}